#!/usr/bin/env python
# coding: utf-8
#
# ---------------------- SMS BULLETIN BOARD -----------------------------------
# Sample application to make use of Fortumo's (www.fortumo.com) 
# Premium SMS-connectivity service on Google App Engine platform.
# Application is able to receive incoming SMS messages from Fortumo
# and stores the messages for later use.
#
# Copyright (c) 2010 Andris Reinman, andris.reinman@gmail.com
#
# Licensed under MIT-style license:
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

from google.appengine.ext import webapp
from google.appengine.ext.webapp import util
from google.appengine.ext import db
from google.appengine.ext.webapp import template
from fortumo import CheckValidRequest, fortumo_config

# Sample DB model to store incoming SMS messages
class Message(db.Model):
  message = db.StringProperty()
  sender = db.StringProperty()
  country = db.StringProperty()
  time = db.DateTimeProperty(auto_now_add = True)

# Sample front page handler to show incoming SMS messages
class MainHandler(webapp.RequestHandler):

  def get(self):
    
    #Load last 100 messages from database
    q = db.GqlQuery("SELECT * FROM Message ORDER BY time DESC")
    messages = q.fetch(100)
    
    # Service parameters like keyword etc. are set in fortumo.yaml 
    template_values = {
        "countries": fortumo_config["countries"],
        "messages": messages
    }
    
    # print out the response from the parsed template file
    self.response.out.write(template.render("front.html", template_values))


# Handler which receives incoming SMS messages
# URL for the handler would be http://app_id.appspot.com/receiver
# NB! SET REQUEST CHARACTER ENCODING TO UTF-8 IN FORTUMO ADMIN PANEL!
#     Edit->Character encoding->Change, select UTF-8 and Save
class ReceiveSMSHandler(webapp.RequestHandler):
  def get(self):
    # Check the validity of the request
    # Matches the IP and signature
    if not CheckValidRequest(self.request.params):
      self.response.out.write("Invalid request!")
      return
    
    # Database transaction needs to be in a function
    # Transaction is needed for a greater stability -
    #    if DB is currently down, the action is repeated several times
    def insert_sms():
      msg = Message()
      # "message" needs to be converted from Latin 1 to Unicode
      msg.message = self.request.get("message")
      msg.sender = self.request.get("sender")
      msg.country = self.request.get("country")
      msg.put()

    db.run_in_transaction(insert_sms)
    
    # Response that will be sent back as a SMS, max 120 chars
    self.response.out.write("Message received, thank you!")


def main():
  application = webapp.WSGIApplication([('/', MainHandler),
                                        ('/receive', ReceiveSMSHandler)],
                                       debug=True)
  util.run_wsgi_app(application)


if __name__ == '__main__':
  main()
